import moment from 'moment';
import logout from './logout';
import ServiceInfoManager from './ServiceInfoManager';
import { setTokenInfo } from './loginStatus';
import AsyncStorage from './AsyncStorage';
import request from './request';
import global from './global';
import { getAppIDInfo } from '../config/template';

function aepRequestOption(appID: string, options: IRequestOptions) {
  const headers: IRequestHeaders = {
    'Content-Type': 'application/json',
    Version: '1.0',
    'X-Gizwits-Application-Id': appID,
    ...options.headers,
  };
  const newOptions = { ...options, headers };
  newOptions.mode = 'cors';
  if (newOptions.body !== undefined) {
    const body = { appKey: appID, data: newOptions.body, version: '1.0' };
    newOptions.data = body;
  }
  return newOptions;
}

function cozeRequestOption(appID: string, options: IRequestOptions) {
  const headers: IRequestHeaders = {
    'Content-Type': 'application/json',
    Version: '1.0',
    'X-Gizwits-Application-Id': appID,
    ...options.headers,
  };
  const newOptions = { ...options, headers };
  newOptions.mode = 'cors';
  if (newOptions.body !== undefined) {
    newOptions.data = newOptions.body;
  }
  return newOptions;
}

async function refreshToken({
  aepApi,
  appID,
}: {
  aepApi: string;
  appID: string;
}) {
  // eslint-disable-next-line no-shadow
  const localRefreshToken = await AsyncStorage.getItem('refreshToken');
  // count--;
  if (localRefreshToken) {
    let createdAt: string | number = (await AsyncStorage.getItem(
      'createdAt'
    )) as string;
    let expiredAt: string | number = (await AsyncStorage.getItem(
      'expiredAt'
    )) as string;
    createdAt = parseInt(`${createdAt}`, 10);
    expiredAt = parseInt(`${expiredAt}`, 10);
    const now = moment().unix();
    // console.log('refreshToken', now, createdAt, expiredAt);
    // if (count === 1) {
    if ((expiredAt - createdAt) / 2 < now - createdAt) {
      // 离过期时间还有一半的时候续期
      console.log('需要刷新token');
      const url = 'app/user/refresh_token';
      const options = {
        method: 'POST',
        body: {
          clientId: appID,
          refresh: true,
          refresh_token: localRefreshToken,
        },
      };
      const requestOptions = aepRequestOption(appID, options);
      requestOptions.headers.Authorization = global.token;
      const data = await request(aepApi + url, requestOptions).then(
        (result) => {
          // eslint-disable-next-line no-shadow
          const { data, success } = result;
          if (success) {
            let { code } = data;
            code = parseInt(code, 10);
            if (code && code === 200) {
              return data.data;
            }
            return {};
          }
          return {};
        }
      );
      console.log('refreshToken', data);
      if (data && data.refresh_token) {
        const {
          refresh_token: refreshTokenNew,
          token,
          created_at: createdAtNew,
          expired_at: expiredAtNew,
        } = data;
        // 有新的token表示刷新成功
        console.log('请求到有新的token');
        await setTokenInfo({
          token,
          refreshToken: refreshTokenNew,
          createdAt: createdAtNew,
          expiredAt: expiredAtNew,
        });
      }
    }
  }
}

export default async function aepApiRequest<T>(
  url: string,
  options: IRequestOptions,
  withToken = true,
): Promise<IResponseData<T>> {
  const aepApi = await ServiceInfoManager.getAepApiUrl();
  let appID = getAppIDInfo().appId;
  const requestOptions = aepRequestOption(appID, options);
  if (withToken) {
    await refreshToken({ aepApi, appID });
    if (global.token) {
      requestOptions.headers.Authorization = global.token;
    }
  }

  console.log(`aep request ${aepApi + url}`, requestOptions, url);

  return request(aepApi + url, requestOptions).then((result: any) => {
    const { data, success } = result;
    let realSuccess = false;
    let msg = '';
    let resultCode;
    let resultData: any = {};
    if (success) {
      const { message } = data;
      const code = parseInt(`${data.code}`, 10);
      // 请求成功，并且服务器返回200才算是真正的成功
      if (code && code === 200) {
        realSuccess = true;
        resultCode = 200;
        resultData = data.data;
        console.log(`aep result success ${url}`, result);
      } else {
        if (code && (code === 505 || code === 526)) {
          // 505 是未登录  526 是被挤下登录
          console.log('AEP token 无效');
          logout();
        }
        msg = message;
        resultCode = code || 1; // 服务器返回错误
        console.log(`aep result error ${url}`, result);
      }
    } else {
      resultCode = 0; // 网络请求发生错误
      /**
       * 提示网络错误
       */
      console.log(`aep result error ${url}`, result);
      // ToastContainer.error(i18n.t('MAKE_SURE_THE_NETWORK_IS_OPEN'));
    }
    const compiledResult = {
      code: resultCode,
      message: msg,
      success: realSuccess,
      data: resultData,
    };
    // deviceLog.log('result', compiledResult);
    return compiledResult;
  });
}

export async function cozeApiRequest<T>(
  url: string,
  options: IRequestOptions,
): Promise<IResponseData<T>> {
  const aepApi = await ServiceInfoManager.getCozeApiUrl();
  let appID = getAppIDInfo().appId;
  const requestOptions = cozeRequestOption(appID, options);
  if (global.token) {
    requestOptions.headers['X-Gizwits-User-Token'] = global.token;
  }
  console.log(`aep request ${aepApi + url}`, requestOptions, url);
  return request(aepApi + url, requestOptions).then((result: any) => {
    console.log('resultresultresult', result)
    return result
  });
}


export async function paymentApiRequest<T>(
  url: string,
  options: IRequestOptions,
): Promise<IResponseData<T>> {
  const aepApi = await ServiceInfoManager.getPaymentApiUrl();
  let appID = getAppIDInfo().appId;
  const requestOptions = cozeRequestOption(appID, options);
  
  if (global.token) {
    requestOptions.headers['X-Gizwits-User-Token'] = global.token;
  }
  console.log(`aep request ${aepApi + url}`, requestOptions, url);
  return request(aepApi + url, requestOptions).then((result: any) => {
    console.log('resultresultresult', result)
    return result
  });
}
